<template>
  <div style="display: flex; position: relative;">
    <div :class="['c-input-tags', ...areaClass]">
      <div v-if="$slots.prepend" class="c-input-tags__prepend" :style="areaPrependStyle">
        <slot name="prepend" v-bind="{disabled, size, color}"></slot>
      </div>
      <div :class="['c-input-tags__tags', ...areaTagsClass]" :style="areaTagsStyle" @click="handleTagAreaClick">
        <el-tag v-for="(item, ind) in localData" :key="ind"
                :type="item.option.type"
                :size="item.option.size"
                :closable="item.option.closable"
                :disable-transitions="item.option.disableTransitions"
                :hit="item.option.hit"
                :color="item.option.color"
                :effect="item.option.effect"
                @click="handleTagClick(item, ind)"
                @close="handleTagClose(item, ind)">
          {{ item[props.label] || '' }}
        </el-tag>
      </div>
      <div v-if="$slots.append" class="c-input-tags__append" :style="areaAppendStyle">
        <slot name="append" v-bind="{disabled, size, color}"></slot>
      </div>
      <div v-else-if="appendIcon" :class="['c-input-tags__append', ...areaAppendClass]" :style="areaAppendStyle">
        <el-button :disabled="disabled" :icon="appendIcon" @click="handleAppendClick"></el-button>
      </div>
    </div>
  </div>
</template>

<script>
import {deepClone} from "../util/utils";

export default {
  name: "c-input-tags",
  model: {
    prop: 'data',
    event: 'updateData',
  },
  props: {
    // 数据
    data: {
      type: Array,
      default() {
        return [];
      }
    },
    props: {
      type: Object,
      default() {
        return {
          label: "label",
          value: "value"
        }
      }
    },
    // 大小
    size: String,
    // 主题颜色
    color: String,
    // tag大小
    tagSize: String,
    // tag类型
    tagType: {
      type: String,
      default: 'info'
    },
    // tag主题
    tagEffect: String,
    // append图标
    appendIcon: {
      type: String,
      default: 'el-icon-circle-plus-outline'
    },
    // 禁用
    disabled: Boolean,
    // tag点击事件之前触发，能阻止tag点击事件
    tagClickBefore: Function,
    // tag关闭事件之前触发，能阻止tag关闭及事件触发
    tagCloseBefore: Function
  },
  data() {
    return {
      localData: [],
      areaClass: [],
      areaTagsClass: [],
      areaTagsStyle: {},
      areaPrependStyle: {},
      areaAppendStyle: {},
      areaAppendClass: [],
      tagAttrs: ['size', 'type', 'closable', 'disableTransitions', 'hit', 'color', 'effect']
    }
  },
  watch: {
    data: {
      handler: function () {
        this.$nextTick(() => {
          this.init();
        })
      },
      immediate: true,
      deep: true
    }
  },
  created() {
    if (this.$slots.prepend) {
      this.areaTagsClass.push('c-input-tags__tags--prepend');
    }
    if (this.$slots.append || this.appendIcon) {
      this.areaTagsClass.push('c-input-tags__tags--append');
    }
    if (this.size) {
      this.areaClass.push(`c-input-tags--${this.size}`)
    }
    if (this.color) {
      this.areaTagsStyle["border"] = `1px solid ${this.color}`;
      //
      this.areaPrependStyle["border"] = `1px solid ${this.color}`;
      this.areaPrependStyle["border-right"] = 'none';
      this.areaPrependStyle["background-color"] = `${this.color}40`;
      this.areaPrependStyle["color"] = `${this.color}`;
      //
      this.areaAppendStyle["border"] = `1px solid ${this.color}`;
      this.areaAppendStyle["border-left"] = 'none';
      this.areaAppendStyle["background-color"] = `${this.color}40`;
      this.areaAppendStyle["color"] = `${this.color}`;
    }
  },
  methods: {
    init() {
      this.localData = deepClone(this.data);
      this.localData.forEach(item => {
        item.option = item.option || {};
        item.option.size = item.option.size || this.tagSize || this.size;
        item.option.type = item.option.type || this.tagType;
        item.option.closable = item.option.closable || !this.disabled;
        item.option.disableTransitions = item.option.disableTransitions || true;
        item.option.hit = item.option.hit || false;
        item.option.color = item.option.color || '';
        item.option.effect = item.option.effect || this.tagEffect;
      })
    },
    // tag点击
    handleTagClick(tagObj, index) {
      let tagObj2 = deepClone(tagObj);
      // 点击事件前触发
      if (typeof this.tagClickBefore === "function") {
        const res = this.tagClickBefore(tagObj, index);
        if (!res) {
          return res;
        }
      }
      this.$emit("tag-click", tagObj2, index);
    },
    // tag区域点击
    handleTagAreaClick() {
      this.$emit("area-click", deepClone(this.localData), this.resolve);
    },
    handleTagClose(tagObj, index) {
      let tagObj2 = deepClone(tagObj);
      // 关闭事件前触发
      if (typeof this.tagCloseBefore === "function") {
        const res = this.tagCloseBefore(tagObj, index);
        if (!res) {
          return res;
        }
      }
      // 移除
      this.localData.splice(index, 1);
      // 更新绑定数据
      this.resolve(this.localData);
      this.$emit("tag-close", tagObj2, index);
    },
    handleAppendClick() {
      this.$emit("append-click", deepClone(this.localData), this.resolve);
    },
    resolve(data) {
      // 触发change事件
      let changeData = data.map(item => {
        let d = {};
        d[this.props.label] = item[this.props.label];
        d[this.props.value] = item[this.props.value];
        return d;
      });
      this.$emit("updateData", changeData);
      this.$emit("change", changeData);
    }
  }
}
</script>

<style lang="scss">

.c-input-tags {
  width: 100%;
  height: 40px;
  line-height: normal;
  display: inline-table;
  border-collapse: separate;
  border-spacing: 0;
  position: relative;

  &--medium {
    font-size: 18px;
    height: 36px;
  }

  &--small {
    font-size: 16px;
    height: 32px;
  }

  &--mini {
    font-size: 14px;
    height: 28px;
  }

  &__tags {
    vertical-align: middle;
    display: table-cell;
    position: relative;
    width: 100%;
    height: 100%;
    border: 1px solid #DCDFE6;
    border-radius: 4px;
    box-sizing: border-box;
    transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
    background-color: #FFF;
    background-image: none;
    padding: 3px 0;

    &:hover {
      border-color: #C0C4CC;
    }

    .el-tag {
      cursor: pointer;
      margin: 2px 0 2px 6px;

      &--medium {
        .el-icon-close {
          font-size: 21px;
          height: 20px;
          width: 20px;
          line-height: 20px;
        }
      }

      &--small {
        .el-icon-close {
          font-size: 19px;
          height: 18px;
          width: 18px;
          line-height: 18px;
        }
      }

      &--mini {
        .el-icon-close {
          font-size: 17px;
          height: 16px;
          width: 16px;
          line-height: 16px;
        }
      }
    }

    &--prepend {
      vertical-align: middle;
      display: table-cell;
      border-top-left-radius: 0;
      border-bottom-left-radius: 0;
    }

    &--append {
      vertical-align: middle;
      display: table-cell;
      border-top-right-radius: 0;
      border-bottom-right-radius: 0;
    }
  }


  &__prepend, &__append {
    background-color: #f5f7fa;
    vertical-align: middle;
    display: table-cell;
    position: relative;
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    padding: 0 20px;
    width: 1px;
    white-space: nowrap;
    color: #909399;

    &:hover {
      border-color: #C0C4CC;
    }

    &:active {
      background-color: #f4f5f6;
    }

    /**/
    .button.el-button, div.el-select .el-input__inner, div.el-select:hover .el-input__inner, button.el-button, div.el-select .el-input__inner, div.el-select:hover .el-input__inner {
      height: 99%;
      border-color: transparent;
      background-color: transparent;
      color: inherit;
      border-top: 0;
      border-bottom: 0;
    }

    .el-button, .el-input, .el-button, .el-input {
      font-size: inherit;
    }

    .el-button, .el-select, .el-button, .el-select {
      display: inline-block;
      margin: -10px -20px;
    }
  }

  &__prepend {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
    border-right: none;
  }

  &__append {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    border-left: none;
  }


}

</style>
